﻿using System;
using System.Runtime.Serialization;
using Trentacular.Office.Server.Search.FacetedSearch.Providers;

namespace Trentacular.Office.Server.Search.FacetedSearch
{
    /// <summary>
    /// Represents the configuration of a Facet Group to display within the
    /// <see cref="Trentacular.Office.Server.Web.UI.WebParts.FacetedSearchWebPart" />.
    /// </summary>
    [Serializable]
    [DataContract(Namespace = OfficeServerSearchNamespace.Value)]
    public class FacetProviderConfiguration
    {
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="FacetProviderConfiguration"/> class.
        /// </summary>
        public FacetProviderConfiguration()
        {
            this.ID = Guid.NewGuid();
            this.MaxFacetsToDisplay = 10;
            this.MaxCharactersToDisplay = 36;
        }

        /// <summary>
        /// Gets or sets an auto-generated ID that identifies this configuration.
        /// </summary>
        /// <value>An auto-generated ID that identifies this configuration.</value>
        [DataMember(Name = "ID", IsRequired = true, Order = 1)]
        public Guid ID { get; set; }

        /// <summary>
        /// Gets or sets the display name that is used as the facet group heading.
        /// </summary>
        /// <value>The display name that is used as the facet group heading.</value>
        [DataMember(Name = "DisplayName", IsRequired = true, Order = 2)]
        public string DisplayName { get; set; }

        /// <summary>
        /// Gets or sets the name of the facet provider type.
        /// </summary>
        /// <value>The name of the facet provider type.</value>
        [DataMember(Name = "FacetProviderTypeName", IsRequired = true, Order = 3)]
        public string FacetProviderTypeName { get; set; }


        /// <summary>
        /// Gets or sets the max facets to display.
        /// </summary>
        /// <value>The max facets to display.</value>
        [DataMember(Name = "MaxFacetsToDisplay", IsRequired = true, Order = 4)]
        public int MaxFacetsToDisplay { get; set; }

        /// <summary>
        /// Gets or sets the max characters to display for a facet.
        /// </summary>
        /// <value>The max characters to display for a facet.</value>
        [DataMember(Name = "MaxCharactersToDisplay", IsRequired = true, Order = 5)]
        public int MaxCharactersToDisplay { get; set; }

        /// <summary>
        /// Gets or sets the configuration properties.
        /// </summary>
        /// <value>The configuration properties.</value>
        [DataMember(Name = "Properties", EmitDefaultValue = false, Order = 6)]
        public ConfigurationPropertyCollection Properties { get; set; }

        /// <summary>
        /// Creates the facet provider for this configuration.
        /// </summary>
        /// <param name="context">The Faceted Search Context.</param>
        /// <returns>The facet provider for this configuration.</returns>
        public IFacetProvider GetFacetProvider(FacetedSearchContext context)
        {
            if (this.FacetProviderTypeName == null)
                throw new ArgumentNullException("FacetProviderTypeName");

            var facetProviderType = Type.GetType(
                this.FacetProviderTypeName,
                true,
                true);

            var facetProvider = Activator.CreateInstance(facetProviderType)
                as IFacetProvider;

            if (facetProvider == null)
                throw new ArgumentException(
                    string.Format(
                        "Invalid Facet Provider: {0}",
                        this.FacetProviderTypeName
                        ),
                    "FacetProviderTypeName"
                    );

            // Set the Search Context
            facetProvider.FacetedSearchContext = context;

            // Set the Configuration
            facetProvider.Configuration = this;

            return facetProvider;
        }
    }
}
